---
title: Dropdown Menu
description: Shows a menu with options or actions when a user clicks the trigger button.
---

{/* prettier-ignore-start */}
{/* prettier-ignore-end */}

import Code from '@/components/Code.astro';
import { LinkButton } from '@/components/react/LinkButton';
import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
import importedCode from '@rnr/reusables/components/ui/dropdown-menu?raw';

<LinkButton href='https://rn-primitives.vercel.app/dropdown-menu'>Dropdown Menu Primitive</LinkButton>
<LinkButton href='/components/text'>Text Component</LinkButton>
<LinkButton target='_blank' href='https://rnr-showcase.vercel.app/dropdown-menu'>
  Demo
</LinkButton>

<br />

Shows a menu with options or actions when a user clicks the trigger button.

### Installation

<Tabs>
  <TabItem label='CLI'> 
    ```bash
    npx @react-native-reusables/cli@latest add dropdown-menu
    ```
  </TabItem>
  <TabItem label='Manual'>
    <Aside type='tip' title='Dependencies'>
      Before copy/pasting, add the <a href='https://rn-primitives.vercel.app/dropdown-menu' className='text-white font-bold'> dropdown-menu primitive</a> and the <a href='/components/text' className='text-white font-bold'>text component</a> to your project.
    </Aside>

    <br />

    **Copy/paste the following code to `~/components/ui/dropdown-menu.tsx`:**

    <Code code={importedCode} lang='tsx' title='~/components/ui/dropdown-menu.tsx' />
  </TabItem>
</Tabs>


### Usage

<Aside type="caution">

  Requires a `<PortalHost />` as the last child of your `<Root/>` (`app/_layout.tsx`) component

  ```tsx
  import { PortalHost } from '@rn-primitives/portal';

  function Root() {
    return (
      <>
        <Stack />
        {/* Default Portal Host (one per app) */}
        <PortalHost />
      </>
    );
  }
  ```

</Aside>

```tsx
import * as React from 'react';
import Animated, { FadeIn } from 'react-native-reanimated';
import { Button } from '~/components/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from '~/components/ui/dropdown-menu';
import { Text } from '~/components/ui/text';

function Example() {

  return (
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant='outline'>
            <Text>Open</Text>
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent insets={contentInsets} className='w-64 native:w-72'>
          <DropdownMenuLabel>My Account</DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuGroup>
            <DropdownMenuItem>
              <Text>Team</Text>
            </DropdownMenuItem>
            <DropdownMenuSub>
              <DropdownMenuSubTrigger>
                <Text>Invite users</Text>
              </DropdownMenuSubTrigger>
              <DropdownMenuSubContent>
                <Animated.View entering={FadeIn.duration(200)}>
                  <DropdownMenuItem>
                    <Text>Email</Text>
                  </DropdownMenuItem>
                  <DropdownMenuItem>
                    <Text>Message</Text>
                  </DropdownMenuItem>
                  <DropdownMenuSeparator />
                  <DropdownMenuItem>
                    <Text>More...</Text>
                  </DropdownMenuItem>
                </Animated.View>
              </DropdownMenuSubContent>
            </DropdownMenuSub>
            <DropdownMenuItem>
              <Text>New Team</Text>
              <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
            </DropdownMenuItem>
          </DropdownMenuGroup>
          <DropdownMenuSeparator />
          <DropdownMenuItem>
            <Text>GitHub</Text>
          </DropdownMenuItem>
          <DropdownMenuItem>
            <Text>Support</Text>
          </DropdownMenuItem>
          <DropdownMenuItem disabled>
            <Text>API</Text>
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem>
            <Text>Log out</Text>
            <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
  );
}
```

## Props

### DropdownMenu

Extends [`View`](https://reactnative.dev/docs/view#props) props

|     Prop     |           Type           |     Note     |
| :----------: | :----------------------: | :----------: |
| onOpenChange| (value: boolean) => void |                         |
|   asChild    |         boolean          |       _(optional)_      |
|  relativeTo  | 'longPress' \| 'trigger' | Native Only_(optional)_ |

### DropdownMenuTrigger

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |
|  inset  | boolean | _(optional)_ |

### DropdownMenuPortal

|    Prop    |               Type               |         Note          |
| :--------: | :------------------------------: | :-------------------: |
| children\* |         React.ReactNode          |                       |
| forceMount |        true \| undefined         |     _(optional)_      |
|  hostName  |              string              | Web Only _(optional)_ |
| container  | HTMLElement \| null \| undefined | Web Only _(optional)_ |

### DropdownMenuContent

Extends [`View`](https://reactnative.dev/docs/view#props) props

|          Prop           |                     Type                     |           Note           |
| :---------------------: | :------------------------------------------: | :----------------------: |
|         asChild         |                   boolean                    |       _(optional)_       |
|      overlayStyle       |            StyleProp\<ViewStyle>             |       _(optional)_       |
|    overlayClassName     |                    string                    |       _(optional)_       |
|       forceMount        |              true \| undefined               |       _(optional)_       |
|       alignOffset       |                    number                    |       _(optional)_       |
|         insets          |                    Insets                    |       _(optional)_       |
|     avoidCollisions     |                   boolean                    |       _(optional)_       |
|          align          |         'start' \| 'center' \| 'end'         |       _(optional)_       |
|          side           |              'top' \| 'bottom'               |       _(optional)_       |
|       sideOffset        |                    number                    |       _(optional)_       |
| disablePositioningStyle |                   boolean                    | Native Only _(optional)_ |
|          loop           |                   boolean                    |  Web Only _(optional)_   |
|    onCloseAutoFocus     |            (event: Event) => void            |  Web Only _(optional)_   |
|     onEscapeKeyDown     |        (event: KeyboardEvent) => void        |  Web Only _(optional)_   |
|  onPointerDownOutside   |  (event\: PointerDownOutsideEvent) => void   |  Web Only _(optional)_   |
|     onFocusOutside      |      (event: FocusOutsideEvent) => void      |  Web Only _(optional)_   |
|    onInteractOutside    | PointerDownOutsideEvent \| FocusOutsideEvent |  Web Only _(optional)_   |
|    collisionBoundary    |  Element \| null \| Array\<Element \| null>  |  Web Only _(optional)_   |
|         sticky          |            'partial' \| 'always'             |  Web Only _(optional)_   |
|    hideWhenDetached     |                   boolean                    |  Web Only _(optional)_   |

### DropdownMenuGroup

Extends [`Text`](https://reactnative.dev/docs/text#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |

### DropdownMenuLabel

Extends [`Text`](https://reactnative.dev/docs/text#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |

### DropdownMenuItem

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |
| textValue | boolean | _(optional)_ |
| closeOnPress | boolean | _(optional)_ |

### DropdownMenuCheckboxItem

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|     Prop     |           Type           |           Note          |
| :----------: | :----------------------: | :---------------------: |
|   checked*   |         boolean          |                         |
|onCheckedChange*| (value: boolean) => void |                       |
|   textValue* |         string           |                         |
|  asChild     |         boolean          |       _(optional)_      |
| closeOnPress |         boolean          | Native Only_(optional)_ |

### DropdownMenuRadioGroup

Extends [`View`](https://reactnative.dev/docs/view#props) props

|     Prop     |           Type           |           Note          |
| :----------: | :----------------------: | :---------------------: |
|   value*   |         boolean          |                         |
|onValueChange*| (value: boolean) => void |                         |
|  asChild     |         boolean          |       _(optional)_      |

### DropdownMenuRadioItem

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|     Prop     |           Type           |           Note          |
| :----------: | :----------------------: | :---------------------: |
|   value*     |         boolean          |                         |
|onCheckedChange*| (value: boolean) => void |                       |
|  asChild     |         boolean          |       _(optional)_      |
| closeOnPress |         boolean          | Native Only_(optional)_ |

### DropdownMenuSeparator

Extends [`View`](https://reactnative.dev/docs/view#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |
| decorative | boolean | _(optional)_ |

### DropdownMenuSub

Extends [`View`](https://reactnative.dev/docs/view#props) props

|     Prop     |           Type           |     Note     |
| :----------: | :----------------------: | :----------: |
|   asChild    |         boolean          | _(optional)_ |
| defaultOpen  |         boolean          | _(optional)_ |
|     open     |         boolean          | _(optional)_ |
| onOpenChange | (value: boolean) => void | _(optional)_ |

### DropdownMenuSubTrigger

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| textValue | string | _(optional)_ |
| asChild | boolean | _(optional)_ |

### DropdownMenuSubContent

Extends [`Pressable`](https://reactnative.dev/docs/pressable#props) props

|  Prop   |  Type   |     Note     |
| :-----: | :-----: | :----------: |
| asChild | boolean | _(optional)_ |
| forceMount | true /| undefined | _(optional)_ |

### DropdownMenuShortcut

Extends [`Text`](https://reactnative.dev/docs/text#props) props